﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TA.Turbo.Controls;
using System.Web;

namespace TA.Turbo
{
	/// <summary>
	/// Extensions for the Script enum.
	/// </summary>
	public static class _ScriptExtensions
	{
		/// <summary>
		/// Returns the corresponding resource include for a <see cref="Script"/> value.
		/// </summary>
		/// <param name="sThis"></param>
		/// <returns></returns>
		public static ScriptResourceInclude GetInclude(this Script sThis)
		{
			switch (sThis)
			{
				case Script.MouseButton:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Events.MouseButton.js", typeof(Script));
				case Script.EventsBase:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Events.EventsBase.js", typeof(Script));
				case Script.AttachedHandler:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Events.AttachedHandler.js", typeof(Script));
				case Script.DOMReadyHandler:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Events.DOMReadyHandler.js", typeof(Script));
				case Script.HashChangeHandler:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Events.HashChangeHandler.js", typeof(Script));
				case Script.KeyPressHandler:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Events.KeyPressHandler.js", typeof(Script));
				case Script.MouseEnterLeaveHandler:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Events.MouseEnterLeaveHandler.js", typeof(Script));
				case Script.MouseWheelHandler:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Events.MouseWheelHandler.js", typeof(Script));
				case Script.Events:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Events.Events.js", typeof(Script));
				case Script.EventSender:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Events.EventSender.js", typeof(Script));

				case Script.Point:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.SizePos.Point.js", typeof(Script));
				case Script.Size:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.SizePos.Size.js", typeof(Script));
				case Script.SizePos:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.SizePos.SizePos.js", typeof(Script));

				case Script.Number:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Number.js", typeof(Script));
				case Script.Date:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Date.js", typeof(Script));
				case Script.Math:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Math.js", typeof(Script));

				case Script.Array_AddRange:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Array.AddRange.js", typeof(Script));
				case Script.Array_Clear:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Array.Clear.js", typeof(Script));
				case Script.Array_Contains:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Array.Contains.js", typeof(Script));
				case Script.Array_Remove:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Array.Remove.js", typeof(Script));
				case Script.Array_IndexOf:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Array.IndexOf.js", typeof(Script));
				case Script.Array_IndexWhere:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Array.IndexWhere.js", typeof(Script));
				case Script.Array_First:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Array.First.js", typeof(Script));
				case Script.Array_Where:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Array.Where.js", typeof(Script));
				case Script.Array_Select:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Array.Select.js", typeof(Script));

				case Script.Element_SetSelection:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Element.SetSelection.js", typeof(Script));
				case Script.Element_getSelectionStart:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Element.getSelectionStart.js", typeof(Script));
				case Script.Element_getSelectionEnd:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Element.getSelectionEnd.js", typeof(Script));
				case Script.Element_AddClass:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Element.AddClass.js", typeof(Script));
				case Script.Element_RemoveClass:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Element.RemoveClass.js", typeof(Script));
				case Script.Element_HasClass:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Element.HasClass.js", typeof(Script));
				case Script.Element_ClearChildNodes:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Element.ClearChildNodes.js", typeof(Script));
				case Script.Element_PerformRecursive:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Element.PerformRecursive.js", typeof(Script));
				case Script.Element_Contains:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Element.Contains.js", typeof(Script));

				case Script.RegExp_Escape:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.RegExp.Escape.js", typeof(Script));
				case Script.RegExp_Matches:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.RegExp.Matches.js", typeof(Script));
				case Script.RegExp_Replace:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.RegExp.Replace.js", typeof(Script));
		
				case Script.String_Contains:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.Contains.js", typeof(Script));
				case Script.String_EndsWith:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.EndsWith.js", typeof(Script));
				case Script.String_Equals:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.Equals.js", typeof(Script));
				case Script.String_Format:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.Format.js", typeof(Script));
				case Script.String_HTMLEncode:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.HTMLEncode.js", typeof(Script));
				case Script.String_IsNullOrEmpty:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.IsNullOrEmpty.js", typeof(Script));
				case Script.String_PadLeft:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.PadLeft.js", typeof(Script));
				case Script.String_PadRight:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.PadRight.js", typeof(Script));
				case Script.String_Pluralize:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.Pluralize.js", typeof(Script));
				case Script.String_Replace:
					TPage page = HttpContext.Current.Handler as TPage;
					if (page != null)
					{
						if (page.BrowserType == BrowserType.Firefox)
						{
							return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.Replace_FF.js", typeof(Script));
						}
					}
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.Replace.js", typeof(Script));
				case Script.String_StartsWith:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.StartsWith.js", typeof(Script));
				case Script.String_TakeFirst:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.TakeFirst.js", typeof(Script));
				case Script.String_Trim:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.Trim.js", typeof(Script));
				case Script.String_TrimEnd:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.TrimEnd.js", typeof(Script));
				case Script.String_TrimStart:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.String.TrimStart.js", typeof(Script));

				case Script.Location_GetQueryStringParam:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Location.GetQueryStringParam.js", typeof(Script));
				case Script.Location_GetHashParam:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Location.GetHashParam.js", typeof(Script));
				case Script.Location__GetParam:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Extensions.Location._GetParam.js", typeof(Script));

				case Script.Browser:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Browser.js", typeof(Script));
				case Script.Ajax:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Ajax.js", typeof(Script));
				case Script.CSS:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.CSS.js", typeof(Script));
				case Script.Elements:
					if (HttpContext.Current.Request.Browser.Browser.Equals("IE")
						&& HttpContext.Current.Request.Browser.MajorVersion < 8)
					{
						return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Elements_IE.js", typeof(Script));
					}
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Elements.js", typeof(Script));
				case Script.ElementSearch:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.ElementSearch.js", typeof(Script));
				case Script.Cookies:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Cookies.js", typeof(Script));
				case Script.General:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.General.js", typeof(Script));
				case Script.Debug:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Debug.js", typeof(Script));
				case Script.Json:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Json.js", typeof(Script));
				case Script.Char:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.Char.js", typeof(Script));
				case Script.StringBuilder:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.General.StringBuilder.js", typeof(Script));

				case Script.BaseControl:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Controls.BaseControl.js", typeof(Script));
				case Script.BaseComplexControl:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Controls.BaseComplexControl.js", typeof(Script));
				case Script.PropertyDefinition:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Controls.PropertyDefinition.js", typeof(Script));
				case Script.EventDefinition:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Controls.EventDefinition.js", typeof(Script));
				case Script.BaseComplexValueControl:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Controls.BaseComplexValueControl.js", typeof(Script));

				case Script.FieldBinding:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.FieldBinding.js", typeof(Script));
				case Script.Template:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Data.Template.js", typeof(Script));
				case Script.Data:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Data.Data.js", typeof(Script));
				case Script.DataTemplate:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Data.DataTemplate.js", typeof(Script));

				case Script.TurboBase:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.TurboBase.js", typeof(Script));
				case Script.TurboCommon:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.Turbo_common.js", typeof(Script));
				case Script.ResponseValidator:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.ResponseValidator.js", typeof(Script));
				case Script.ResponseUpdatePanel:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.ResponseUpdatePanel.js", typeof(Script));
				case Script.ResponseUpdatePanelInclude:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.ResponseUpdatePanelInclude.js", typeof(Script));
				case Script.ResponseUpdatePanelIncludeCollection:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.ResponseUpdatePanelIncludeCollection.js", typeof(Script));
				case Script.ResponseControl:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.ResponseControl.js", typeof(Script));
				case Script.AjaxResponse:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.AjaxResponse.js", typeof(Script));
				case Script.Turbo:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.Turbo.js", typeof(Script));
				case Script.TurboCookies:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.Turbo_Cookies.js", typeof(Script));
				case Script.TurboAjax:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.Turbo_Ajax.js", typeof(Script));
				case Script.TurboPage:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.Turbo_Page.js", typeof(Script));
				case Script.PostScenario:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.PostScenario.js", typeof(Script));
				case Script.ServerEventSender:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Turbo.ServerEventSender.js", typeof(Script));

				case Script.DataDirection:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Enums.DataDirection.js", typeof(Script));
				case Script.DataType:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Enums.DataType.js", typeof(Script));
				case Script.Orientation:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Enums.Orientation.js", typeof(Script));
				case Script.DropDownTrigger:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Enums.DropDownTrigger.js", typeof(Script));
				case Script.GroupedPagingMode:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.Enums.GroupedPagingMode.js", typeof(Script));

				case Script.ListItem:
					return new ScriptResourceInclude("TA.Turbo.Res.JS.ListControl.ListItem.js", typeof(Script));
			}
			throw new ArgumentOutOfRangeException();
		}
		/// <summary>
		/// Returns an array of <see cref="Script"/>s which are needed for this <see cref="Script"/> to operate.
		/// </summary>
		/// <param name="sThis"></param>
		/// <returns></returns>
		public static Script[] GetDependencies(this Script sThis)
		{
			switch (sThis)
			{
				case Script.Array_Remove:
					return new[] { Script.Array_IndexOf, };

				case Script.String_Trim:
					return new[] { Script.String_TrimEnd, Script.String_TrimStart, };
				case Script.String_Format:
					return new[] { Script.RegExp_Matches, };

				case Script.RegExp_Escape:
					return new[] { Script.StringBuilder, Script.String_Contains, };
				case Script.RegExp_Replace:
					return new[] { Script.StringBuilder, };

				case Script.Location_GetHashParam:
					return new[] { Script.Location__GetParam, };
				case Script.Location_GetQueryStringParam:
					return new[] { Script.Location__GetParam, };
				case Script.Location__GetParam:
					return new[] { Script.RegExp_Escape, };

				case Script.Date:
					return new[] { Script.String_PadLeft, Script.StringBuilder, };
				
				//case Script.EventsBase:
				//  return new[] { };
				case Script.AttachedHandler:
					return new[] { Script.EventsBase, };
				case Script.DOMReadyHandler:
					return new[] { Script.AttachedHandler, Script.Browser, };
				case Script.MouseWheelHandler:
					return new[] { Script.Browser, Script.AttachedHandler, };
				case Script.HashChangeHandler:
					return new[] { Script.AttachedHandler, };
				case Script.MouseEnterLeaveHandler:
					return new[] { Script.AttachedHandler, };
				case Script.KeyPressHandler:
					return new[] { Script.AttachedHandler, };
				case Script.Events:
					return new[] { Script.Browser, Script.AttachedHandler, };
				case Script.EventSender:
					return new[] { Script.Events, };

				case Script.SizePos:
					return new[] { Script.Point, Script.Size, };

				case Script.Ajax:
					return new[] { Script.StringBuilder, Script.Browser, };
				case Script.CSS:
					return new[] { Script.Elements };
				case Script.Elements:
					return new[] { Script.Browser, };
				case Script.ElementSearch:
					return new[] { Script.Elements, Script.StringBuilder, Script.Char, Script.Element_HasClass, Script.Array_AddRange, Script.Array_Contains, };
				case Script.Cookies:
					return new[] { Script.StringBuilder, };
				case Script.Json:
					return new[] { Script.StringBuilder, };


				case Script.FieldBinding:
					return new[] { Script.TurboBase, Script.DataDirection, Script.DataType, Script.Json, Script.String_IsNullOrEmpty, };
				case Script.PostScenario:
					return new[] { Script.General, Script.Json, Script.EventSender, Script.TurboCommon, };
				case Script.TurboCommon:
					return new[] { Script.TurboBase, Script.General, Script.Elements, Script.Events, };
				case Script.Data:
					return new Script[] { Script.Element_PerformRecursive, Script.RegExp_Matches, Script.String_Format, };
				case Script.Turbo:
					return new[] { Script.Ajax, Script.Json, Script.TurboCommon, Script.PostScenario, Script.AjaxResponse, Script.String_Replace, };
				case Script.TurboCookies:
					return new[] { Script.TurboBase, Script.Cookies, Script.RegExp_Escape, Script.String_Contains, };
				case Script.ServerEventSender:
					return new[] { Script.EventSender, Script.Turbo, };
				case Script.ResponseUpdatePanel:
					return new[] { Script.ResponseUpdatePanelIncludeCollection, };
				case Script.ResponseUpdatePanelIncludeCollection:
					return new[] { Script.ResponseUpdatePanelInclude, };

				case Script.EventDefinition:
					return new[] { Script.General, Script.TurboCommon, };
				case Script.PropertyDefinition:
					return new[] { Script.TurboBase, };
				case Script.BaseControl:
					return new[] { Script.TurboBase, Script.PropertyDefinition, };
				case Script.BaseComplexControl:
					return new[] { Script.BaseControl, };
				case Script.BaseComplexValueControl:
					return new[] {
						Script.BaseComplexControl, 
						//Script.FieldBinding, // trying to remove this somehow
					};

				case Script.ListItem:
					return new[] { Script.TurboBase, Script.Json, Script.String_IsNullOrEmpty, };

				case Script.Template:
					return new[] { Script.TurboBase, Script.Json, Script.Element_PerformRecursive, Script.String_Replace, };
				case Script.DataTemplate:
					return new[] { Script.Template, Script.Data, };
			}
			return new Script[0];
		}
	}
}